Skip to main content

配置

在每个触发器、搜索或创建操作中,您可以在 operation 指令下,通过 inputFields 提供一个对象数组来定义字段。

这些字段有各种选项可供配置。下面是一个简要示例:

const App = {// ...creates:{create_recipe:{// ...operation:{// 使用对象数组是最简单的方式inputFields:[{key:"title",required:true,label:"Title of Recipe",helpText:"Name your recipe!",},{key:"style",required:true,choices:{mexican:"Mexican",italian:"Italian"},},],perform:()=>{},},},},};

值得注意的是,字段有不同的类型,这些类型在 Zap 编辑器中可能显示和行为不同。默认字段显示为单行输入字段。

类型行为
string接受文本输入。
text显示大型文本输入框,接受文本输入。
code显示大型输入框,使用固定宽度字体,接受文本输入。
integer接受整数值。
number接受任何数值,包括小数。
boolean显示下拉菜单,提供 true 和 false 选项,并传递 true 或 false 值。
datetime接受精确的或易读的日期时间值,并传递 ISO 格式化的时间字符串。
file接受文件对象或字符串。如果字符串中提供 URL,Zapier 会自动发送 GET 请求获取该文件。否则,将生成一个文本文件。
password以隐藏方式显示输入字符,接受文本输入,且不接受来自先前步骤的输入。
copy不允许用户输入数据。只显示字段的 Markdown 格式化帮助文本,作为 Zap 编辑器中的富文本注释。适合用于向用户显示重要通知。

您可以在我们的 Field Schema 中找到有关不同字段模式选项的更多详细信息。

自定义/动态字段

在某些情况下,您可能需要提供动态生成的字段——尤其是自定义字段。这在 CRM、表单软件、数据库和其他高度可定制的平台中很常见。不是提供显式的字段定义,您可以提供一个函数,我们会评估该函数以返回字段列表——将动态字段与静态字段合并。

在字段检索过程中,您应该看到 bundle.inputData 部分已部分填充用户提供的数据——即使在字段检索中。这允许您在字段中构建层次关系(例如,只显示先前选择的项目的相关问题)。

返回动态字段列表的函数不能在该列表中包含其他函数来调用动态字段。

const recipeFields = async (z, bundle) => {  const response = await z.request("https://example.com/api/v2/fields.json");  // 如果您使用 zapier-platform-core v9 或更早版本,请调用 response.throwForStatus()  // 应该返回一个数组,如 [{"key":"field_1"},{"key":"field_2"}]  return response.data;  // 如果您使用 core v9 或更早版本,请使用 response.json};
const App = {// ...creates:{create_recipe:{// ...operation:{// 使用对象数组是最简单的方式inputFields:[{key:"title",required:true,label:"Title of Recipe",helpText:"Name your recipe!",},{key:"style",required:true,choices:{mexican:"Mexican",italian:"Italian"},},recipeFields,// 内联提供一个函数 - 我们会合并结果!],perform:()=>{},},},},};

此外,如果某个字段会影响动态字段的生成,您可以设置属性 altersDynamicFields: true。这会通知 Zapier UI,每当该字段的值更改时,都需要重新计算输入字段。例如,假设一个名为“Dessert Type”的静态下拉菜单的选择会决定动态字段生成函数是否包含“With Sprinkles?”字段。如果一个输入字段的值会影响其他字段,这是一个重要的属性。

module.exports = {  key: "dessert",  noun: "Dessert",  display: {    label: "Order Dessert",    description: "Orders a dessert.",  },  operation: {    inputFields: [      {        key: "type",        required: true,        choices: {          1: "cake",          2: "ice cream",          3: "cookie",        },        altersDynamicFields: true,      },      function(z, bundle) {        if (bundle.inputData.type === "2") {          return [{ key: "with_sprinkles", type: "boolean" }];        }        return [];      },    ],    perform: function(z, bundle) {      /* ... */    },  },};

只有下拉菜单支持 altersDynamicFields

在使用动态字段时,字段将在三个不同上下文中被检索:

  • 如上所述,每当带有 altersDynamicFields 的字段值更改时。
  • 每当 Zap 编辑器打开“设置”部分时,用于触发器或操作。
  • 每当在编辑器的“设置”部分底部点击“刷新字段”按钮时。

请确保相应设置您的代码——例如,不要依赖任何输入字段已经具有值,因为在“设置”部分首次加载时,它们不会具有值。

动态下拉菜单

请参阅动态下拉菜单

计算字段

在 OAuth 和 Session Auth 中,Zapier 会自动存储集成 auth API 响应的所有值,即 OAuth 中的 getAccessTokenrefreshAccessToken,以及 Session Auth 中的 getSessionKey

您可以在这些响应中返回额外的字段,除了预期的 access_tokenrefresh_token(针对 OAuth)以及 sessionKey(针对 Session Auth)。这些字段将保存在 bundle.authData 中。您可以在后续的任何 API 调用中引用这些字段。

注意:仅 OAuth 和 Session Auth 支持计算字段。

如果您希望 Zapier 验证这些额外字段的存在,则需要使用计算字段。如果在您的集成中定义了计算字段,Zapier 会在运行身份验证测试 API 调用时检查这些字段是否存在。

计算 field 像其他 field 一样工作,但带有 computed: true 属性,以及 required: false(因为用户无法自行输入计算 field)。在 API 调用中引用计算 field 时,使用 { {bundle.authData.field} },将 field 替换为您的测试 API 调用响应中的该字段名称。

您可以在OAuth2Session Auth 示例部分中看到计算字段的示例。

嵌套和子级(行项目)字段

当您的操作需要接受项目数组时,您可以包含一个带有 children 属性的输入字段。children 属性接受一个字段 列表,这些字段可用于该数组中的每个项目。

const App = {// ...operation:{// ...inputFields:[{key:"lineItems",children:[{key:"lineItemId",type:"integer",label:"Line Item ID",required:true,},{key:"name",type:"string",label:"Name",required:true,},{key:"description",type:"string",label:"Description",},],},],// ...},};

定义额外的输入字段元数据

版本 15.19.0 开始,输入字段可以定义一个 meta 属性,该属性包含一个对象,键为字符串,值为字符串、整数或布尔值。此 meta 对象将作为 bundle.meta 的一部分,在 inputFields 键下可用。例如,如果一个键为 create_recipe 的输入字段定义了 meta 对象,那么在 perform 方法期间,此对象将可在 bundle.meta.inputFields['create_recipe'] 中访问。

这种上下文存储在处理动态生成的字段时特别有用,因为您可能希望使用这些额外数据来更改触发器或操作的 perform 方法中的某些逻辑。

const fetchStringOrDatetimeFields = async (z, bundle) => {  // 应该返回一个数组,如 [{'key':'field_1'},{'key':'field_2_datetime'}]  const response = await z.request("https://example.com/api/v2/fields.json");  const resultingFields = [];  response.data.forEach((field) => {    if (field.key.endsWith("_datetime")) {      resultingFields.push({        key: field.key,        // 将 meta 设置为解析为日期时间        meta: {          internalType: "datetime",        },      });    } else {      resultingFields.push({        key: field.key,        // 将 meta 设置为字符串(默认)        meta: {          internalType: "string",        },      });    }  });  return resultingFields;};
const App = {// ...creates:{create_agenda:{// ...operation:{inputFields:[fetchStringOrDatetimeFields],perform:async(z,bundle)=>{for(const[key,value]of Object.entries(bundle.inputData)) {const fieldMeta = bundle.meta[key] || {};if(fieldMeta.internalType === "datetime") {// 将 value 处理为日期时间}else{// 将 value 处理为字符串}}},},},},};